<template>
  <div class="container">
    <a-card class="general-card" :title="$route.meta.locale">
      <table-search
        v-permission="'system:role:query'"
        :fileds="searchFileds"
        @search="search"
        @reset="search"
      ></table-search>
      <xTable
        v-model:refresh="refresh"
        v-model:selected-keys="selectedKeys"
        :params="params"
        :columns="tableColumns"
        row-key="roleId"
        :http="{
          list: getListData,
          del: delRole,
          exported: role,
          batchDel: delRole,
        }"
        :http-permission="{
          del: 'system:role:remove',
          exported: 'system:role:export',
          more: 'system:role:edit',
        }"
      >
        <template #operation-default>
          <div class="item">
            <a-button
              v-permission="'system:role:add'"
              type="outline"
              @click="editOpen(null)"
            >
              新增
            </a-button>
          </div>
          <div v-permission="'system:role:edit'" class="item">
            <a-button
              type="outline"
              status="success"
              @click="editOpen(selectedKeys)"
            >
              编辑
            </a-button>
          </div>
        </template>
        <template #status="{ row }">
          <a-switch
            v-model="row.status"
            checked-value="0"
            unchecked-value="1"
            :data-id="row.roleId"
            :data-rolename="row.roleName"
            @change="switchChange"
          />
        </template>
        <template #optional="{ row }">
          <a-button
            v-permission="'system:role:edit'"
            type="text"
            status="success"
            @click="editOpen(row.roleId)"
          >
            编辑
          </a-button>
        </template>
        <template #more="{ row }">
          <a-doption
            v-permission="'system:role:edit'"
            @click="doptionClick('data', row)"
            >数据权限</a-doption
          >
          <a-doption
            v-permission="'system:role:edit'"
            @click="doptionClick('user', row)"
            >分配用户</a-doption
          >
        </template>
      </xTable>
    </a-card>
    <EditModal
      ref="edit"
      :default-value="{ orderNum: 0, menuType: 'M', status: defaultStatus }"
      :fields="editFields"
      :http-add="addRole"
      :http-edit="updateRole"
      :http-get="getRoleHttp"
      :get-handler="getHandler"
      :handler="handler"
      @reload="refresh = true"
    >
    </EditModal>

    <EditModal
      ref="dataEdit"
      :default-value="{ roleName: 0, roleKey: 'M' }"
      :fields="dataFields"
      :http-add="addRole"
      :http-edit="dataScope"
      :http-get="getDataScopeHttp"
      :get-handler="getHandler"
      :handler="dataHandler"
      @reload="refresh = true"
    >
    </EditModal>
  </div>
</template>

<script lang="ts" setup>
  import { reactive, ref, computed, toRaw } from 'vue';
  import { addDateRange } from '@/utils/index';
  import { Message, Modal } from '@arco-design/web-vue';
  import { getDict } from '@/utils/dict';
  import { useRouter } from 'vue-router';
  import {
    getListData,
    getRole,
    addRole,
    updateRole,
    changeRoleStatus,
    delRole,
    dataScope,
  } from '@/api/system/role';
  import { role } from '@/api/exportFile';
  import {
    treeselect as menuTreeselect,
    roleMenuTreeselect,
  } from '@/api/system/menu';
  import {
    treeselect as deptTreeselect,
    roleDeptTreeselect,
  } from '@/api/system/dept';

  import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';

  const router = useRouter();
  const dict = getDict('sys_normal_disable');
  const edit = ref();
  const dataEdit = ref();

  const selectedKeys = ref([]);
  // 定义查询字段
  const searchFileds: Array<any> = reactive([
    {
      span: 5,
      field: 'roleName',
      placeholder: '请输入角色名称',
      label: '角色名称',
      tag: 'a-input',
      initValue: '',
    },
    {
      span: 5,
      field: 'roleKey',
      placeholder: '请输入权限字符',
      label: '权限字符',
      tag: 'a-input',
      initValue: '',
    },
    {
      span: 5,
      field: 'status',
      placeholder: '请选择角色状态',
      label: '状态',
      initValue: '',
      tag: 'a-select',
      attrs: {
        options: [
          { value: '1', label: '开启' },
          { value: '2', label: '禁用' },
        ],
      },
    },
    {
      span: 5,
      field: 'dateRange',
      label: '创建时间',
      tag: 'a-range-picker',
      initValue: [],
    },
  ]);
  // 定义表格字段
  const tableColumns: Array<TableColumnData> = reactive([
    {
      dataIndex: 'roleId',
      title: '角色编号',
    },
    {
      dataIndex: 'roleName',
      title: '角色名称',
    },
    {
      dataIndex: 'roleKey',
      title: '权限字符',
    },
    {
      dataIndex: 'roleSort',
      title: '显示顺序',
    },
    {
      dataIndex: 'status',
      title: '状态',
      slotName: 'status',
    },
    {
      dataIndex: 'createTime',
      title: '创建时间',
    },
    {
      dataIndex: 'optional',
      title: '操作',
      slotName: 'optional',
    },
  ]);

  const editFields: Array<any> = reactive([
    {
      key: 'roleName',
      label: '角色名称',
      placeholder: '请输入角色名称',
      tag: 'a-input',
      attrs: {},
      decorator: {
        rules: [{ required: true, message: '请输入角色名称' }],
      },
    },
    {
      key: 'roleKey',
      label: '权限字符',
      placeholder: '请输入权限字符',
      tag: 'a-input',
      attrs: {},
      decorator: {
        rules: [{ required: true, message: '请输入权限字符' }],
      },
    },
    {
      key: 'roleSort',
      label: '角色顺序',
      placeholder: '请输入角色顺序',
      tag: 'a-input-number',
      attrs: {},
      decorator: {
        rules: [{ required: true, message: '请输入角色顺序' }],
      },
    },
    {
      key: 'status',
      label: '状态',
      placeholder: '请选择状态',
      tag: 'a-radio-group',
      decorator: {
        rules: [{ required: false, message: '请选择状态' }],
      },
      attrs: {
        options: dict.sys_normal_disable,
      },
    },
    {
      key: 'menuIds',
      label: '菜单权限',
      placeholder: '请选择菜单权限',
      tag: 'data-tree',
      decorator: {
        rules: [{ required: true, message: '请选择菜单权限' }],
      },
      attrs: {
        getData: menuTreeselect,
      },
    },
    {
      key: 'remark',
      label: '备注',
      placeholder: '请输入备注',
      tag: 'a-input',
      attrs: {},
      decorator: {
        rules: [{ required: false, message: '请输入备注' }],
      },
    },
  ]);
  const dataFields: Array<any> = reactive([
    {
      key: 'roleName',
      label: '角色名称',
      placeholder: '请输入角色名称',
      tag: 'a-input',
      attrs: {
        disabled: true,
      },
      decorator: {
        rules: [{ required: true, message: '请输入角色名称' }],
      },
    },
    {
      key: 'roleKey',
      label: '权限字符',
      placeholder: '请输入权限字符',
      tag: 'a-input',
      attrs: {
        disabled: true,
      },
      decorator: {
        rules: [{ required: true, message: '请输入权限字符' }],
      },
    },
    {
      key: 'dataScope',
      label: '数据范围',
      placeholder: '请输入权限字符',
      tag: 'a-select',
      attrs: {
        options: [
          {
            value: '1',
            label: '全部数据权限',
          },
          {
            value: '2',
            label: '自定数据权限',
          },
          {
            value: '3',
            label: '本部门数据权限',
          },
          {
            value: '4',
            label: '本部门及以下数据权限',
          },
          {
            value: '5',
            label: '仅本人数据权限',
          },
        ],
      },
      decorator: {
        rules: [{ required: true, message: '请输入权限字符' }],
      },
    },
    {
      key: 'deptIds',
      label: '菜单权限',
      placeholder: '请选择菜单权限',
      tag: 'data-tree',
      decorator: {
        rules: [{ required: true, message: '请选择菜单权限' }],
      },
      attrs: {
        getData: deptTreeselect,
      },
      show: (value: any) => {
        return Number(value.dataScope) === 2;
      },
    },
  ]);
  const refresh = ref(true);
  // 定义表格查询参数
  const params = ref({
    dateRange: [],
  });
  const defaultStatus = computed(() => {
    if (dict.sys_normal_disable.value <= 0) {
      return '0';
    }
    const list = toRaw(dict.sys_normal_disable);
    return list.value.find((item: { default: any }) => item.default).value;
  });
  // 定义搜索方法
  const search = (data: any) => {
    params.value = addDateRange(data, data?.dateRange);
    refresh.value = true;
  };

  const editOpen = async (keys: any | any[]) => {
    if (Array.isArray(keys) && keys.length === 1) {
      edit.value.show(keys[0]);
    } else if (!Array.isArray(keys)) {
      edit.value.show(keys);
    } else if (Array.isArray(keys) && keys.length < 1) {
      Message.warning('必须选中一条数据');
    } else if (Array.isArray(keys) && keys.length > 1) {
      Message.warning('只能选中一条数据');
    }
  };
  // 获取角色详情
  const getRoleHttp = async (id: string) => {
    const res = await Promise.all([getRole(id), roleMenuTreeselect(id)]);
    let role: { [x: string]: any } = {};
    if (res[0].code !== 200) {
      Message.warning(res[0].msg);
    } else {
      role = res[0].data;
    }
    if (res[1].code !== 200) {
      Message.warning(res[1].msg);
    } else {
      role.menuIds = {
        checks: res[1].checkedKeys,
        checkStrictly: role.menuCheckStrictly,
      };
    }
    return {
      code: 200,
      data: role,
    };
  };
  const getHandler = ({ data }: { [x: string]: any }) => {
    return {
      ...data,
      roleSort: Number(data?.roleSort),
    };
  };
  const handler = (data: { [x: string]: any }) => {
    return {
      ...data,
      menuIds: data.menuIds.checks,
      menuCheckStrictly: data.menuIds.checkStrictly,
    };
  };
  // 禁用启用角色
  const switchChange = (value: any, ev: any) => {
    let dataset = {
      id: ev.target.getAttribute('data-id'),
      rolename: ev.target.getAttribute('data-rolename'),
    };
    if (!dataset.id) {
      dataset = ev.srcElement.parentNode.dataset;
    }
    Modal.info({
      title: '提示',
      content: `确定${Number(value) === 0 ? '启用' : '禁用'}“${
        dataset.rolename
      }”角色吗`,
      hideCancel: false,
      onOk: () => {
        changeRoleStatus(dataset.id, value).then(({ code, msg }) => {
          refresh.value = true;
          if (code !== 200) {
            Message.warning(msg);
          }
        });
      },
      onCancel: () => {
        refresh.value = true;
      },
    });
  };
  // 选择
  const doptionClick = (key: string, row: any) => {
    if (key === 'data') {
      dataEdit.value.show(row.roleId);
    } else {
      router.push({
        name: 'SystemRoleUsers',
        params: {
          roleId: row.roleId,
        },
      });
    }
  };
  const getDataScopeHttp = async (id: string) => {
    const res = await Promise.all([getRole(id), roleDeptTreeselect(id)]);
    let role: { [x: string]: any } = {};
    if (res[0].code !== 200) {
      Message.warning(res[0].msg);
    } else {
      role = res[0].data;
    }
    if (res[1].code !== 200) {
      Message.warning(res[1].msg);
    } else {
      role.deptIds = {
        checks: res[1].checkedKeys,
        checkStrictly: role.deptCheckStrictly,
      };
    }
    return {
      code: 200,
      data: role,
    };
  };
  const dataHandler = (data: { [x: string]: any }) => {
    return {
      ...data,
      deptIds: data.deptIds.checks,
      deptCheckStrictly: data.deptIds.checkStrictly,
    };
  };
</script>

<script lang="ts">
  export default {
    name: 'Role',
  };
</script>

<style scoped lang="less">
  .operation-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    margin-bottom: 20px;
    .item {
      margin-left: 8px;
    }
  }
  .container {
    // padding: 0 20px 20px 20px;
  }
  :deep(.arco-table-th) {
    &:last-child {
      .arco-table-th-item-title {
        margin-left: 16px;
      }
    }
  }
</style>
